package cn.udrm.elasticsearch.fulltext;

import cn.udrm.elasticsearch.fileread.*;
import cn.udrm.elasticsearch.model.Article;
import cn.udrm.elasticsearch.util.*;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Slf4j
@Component
public class BuildFileIndex {

    @Resource
    private JestClient jestClient;

  /**
     * 创建索引
     * @param file
     * @param indexName：索引名称
     * @param docType：文档类型
     */
    public void createIndex(File file,String indexName,String docType){
        //用MD5生成文件指纹,搜索该指纹是否已经索引
        String fileFingerprint = Md5CaculateUtil.getMD5(file);
        try {
            if(!isIndex(file,indexName,docType,fileFingerprint)){
                Article article = new Article();
                article.setId(UUID.randomUUID().toString());
                article.setTitle(file.getName());
                article.setAuthor("许荣北");
                article.setPath(file.getPath());
                article.setLength(file.length());
                article.setState("success");
                article.setContent(readToString(file, getFileExt(file)));
                article.setFileFingerprint(fileFingerprint);
                if(article.getContent()==null||article.getContent().trim().length()==0){
                    article.setState("empty");
                    article.setContent("文档内容无法识别！");
                    Index index = new Index.Builder(article).index(indexName).type(docType).build();
                    jestClient.execute(index);
                    return;
                }
                //2\. 构建一个索引
                Index index = new Index.Builder(article).index(indexName).type(docType).build();
                JestResult jestResult=jestClient.execute(index);
                if(!jestResult.isSucceeded()){
                    log.info("=========添加索引文档失败！length："+file.length()+"，path："+file.getPath());
                }
                /*if(jestResult.isSucceeded()){
                    log.info("=========添加索引文档成功！length："+file.length()+" path："+file.getPath());
                }*/
            }else{
                //log.info("============最新文件无需更新===========");
            }
        } catch (Exception e) {
            StringBuffer stringBuffer=new StringBuffer();
            Article article = new Article();
            article.setId(UUID.randomUUID().toString());
            article.setTitle(file.getName());
            article.setAuthor("许荣北");
            article.setState("failure");
            article.setPath(file.getPath());
            article.setLength(file.length());
            stringBuffer.append(e.getClass().getName()+"："+e.getMessage());
            StackTraceElement[] elements=e.getStackTrace();
            for(StackTraceElement element:elements){
                stringBuffer.append(element.toString());
            }
            article.setContent(stringBuffer.toString());
            article.setFileFingerprint(fileFingerprint);
            Index index = new Index.Builder(article).index(indexName).type(docType).build();
            try {
                if(!jestClient.execute(index).getId().isEmpty()){
                    log.info("！！！！！！！！构建异常索引文档成功！！！！！！！！！"+" path："+file.getPath());
                }
            } catch (IOException ex) {
                log.error("添加异常索引失败！",ex);
            }
            log.error("解析文件异常！path："+file.getPath());
        }
    }

    /**
     * 判断索引文件内容是否更改
     * @param file
     * @param indexName：索引名称
     * @param docType：文档类型
     * @param fileFingerprint：文件指纹
     * @return
     */
    public boolean isIndex(File file,String indexName,String docType,String fileFingerprint) throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("fileFingerprint", fileFingerprint));
        Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(indexName).addType(docType).build();
        //执行
        SearchResult searchResult = jestClient.execute(search);
        if(searchResult.isSucceeded()){
            List<Article> articles = searchResult.getSourceAsObjectList(Article.class,false);
            if(articles!=null&&articles.size()>0){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    /**
     * 读取文件内容
     * @param file
     * @param fileType
     * @return
     * @throws IOException
     */
    public String readToString(File file,String fileType) throws Exception {
        long l=System.currentTimeMillis();
        StringBuffer result = new StringBuffer();
        switch (fileType){
            case FileType.TXT:
                result.append(TXTReadContent.getTxtContent(file));
                break;
            case FileType.OFD:
                result.append(OFDReadContent.getOfdContent(file));
                break;
            case FileType.PDF:
                result.append(PDFReadContent.getPdfContent(file));
                break;
            case FileType.PPT:
                result.append(PPTReadContent.getPptContent(file));
                break;
            case FileType.PPTX:
                result.append(PPTReadContent.getPptxContent(file));
                break;
            case FileType.DOC:
               result.append(WordReadContent.getDocContent(file));
                break;
            case FileType.DOCX:
                result.append(WordReadContent.getDocxContent(file));
                break;
            case FileType.XLS:
                result.append(ExcelReadContent.getXlsContent(file));
                break;
            case FileType.XLSX:
                result.append(ExcelReadContent.getXlsxContent(file));
                break;
            default:
                break;
        }
        long cost=System.currentTimeMillis()-l;
        if(cost>1000){
            log.info("===============解析文件耗时："+(System.currentTimeMillis()-l)+"ms，length："+file.length()+"，path："+file.getPath());
        }
        return result.toString();
    }

    public String getFileExt(File file){
        String filename = file.getName();
        String[] strArray = filename.split("\\.");
        int suffixIndex = strArray.length - 1;
        return strArray[suffixIndex];
    }

    public String getFilePrefix(File file){
        String filename = file.getName();
        String[] strArray = filename.split("\\.");
        return strArray[0];
    }
}
